/**
 *  Name:            Dennis Jasch
 *  Matrikel-Nummer: 167300
 *  Projekt-Name:    Aufgabe2
 *  Paket-Name:      praesentation
 *  Datei-Name:      Benutzerkommunikation.java
 *  Erstelldatum:    19.11.2006 16:03:44
 */
package praesentation;

import logik.Uebungsgruppen;
import daten.TeilnehmendePerson;
import ea.Ausgabe;
import ea.Eingabe;

/**
 * Ein Objekt dieser Klasse stellt eine Konsolenoberflaeche zur Verwaltung von Uebungsgruppen-Objekten dar.
 * 
 * @author Dennis Jasch
 * @version 0.2 vom 30.11.2006
 */
public class Benutzerkommunikation
  {
  /**
   * Konstante fuer die Benutzerangabe zur Eingabe eines Teilnehmers
   */
  private final static char TEILNEHMER_EINGEBEN = '1';

  /**
   * Konstante fuer die Benutzerangabe zur Anzeige aller Gruppen
   */
  private final static char GRUPPE_ANZEIGN = '3';

  /**
   * Konstante fuer die Benutzerangabe zur Anzeige aller Teilnehmer
   */
  private final static char TEILNEHMER_ANZEIGEN = '2';

  /**
   * Konstante fuer die Benutzerangabe zum Beenden des Programms
   */
  private final static char ENDE = '4';

  /**
   * Privates Objekt zur Verwaltung der Ubeungsgruppen und deren Teilnehmer.
   */
  private Uebungsgruppen uebungsgruppen;

  /**
   * Zeigt den Startbildschirm ein.
   */
  public Benutzerkommunikation()
    {
    this.zeigeSplashScreen();
    }

  /**
   * Methode zur Eingabe und Auswertung der Benutzeraktionen.
   * 
   * @param uebungsgruppen Ein Uebungsgruppen-Objekt, welches verwaltet werden soll.
   */
  public void verwalteUebungsgruppen(Uebungsgruppen uebungsgruppen)
    {
    this.uebungsgruppen = uebungsgruppen;
    char steuerZeichen;

    do
      {
      this.zeigeAuswahlMenuAn();
      steuerZeichen = Eingabe.liesChar();
      switch (steuerZeichen)
        {
        case Benutzerkommunikation.GRUPPE_ANZEIGN:
          {
          Ausgabe.neueZeile();
          for (int i = 1; i <= this.uebungsgruppen.MAX_ANZAHL_GRUPPEN; i++)
            {
            Ausgabe.neueZeile();
            Ausgabe.schreib("Uebungsgruppe " + i + ": ");
            this.zeigeListeAn(this.uebungsgruppen.getUebungsgruppenTeilnehmer(i));
            Ausgabe.neueZeile();
            }
          break;
          }
        case Benutzerkommunikation.TEILNEHMER_EINGEBEN:
          {
          this.teilnehmerEingeben();
          break;
          }
        case Benutzerkommunikation.TEILNEHMER_ANZEIGEN:
          {
          this.zeigeListeAn(this.uebungsgruppen.getAlleTeilnehmer());
          Ausgabe.neueZeile();
          break;
          }
        default:
          {
          if (steuerZeichen != Benutzerkommunikation.ENDE)
            Ausgabe.schreib("Ungueltige Option!");
          break;
          }
        }
      } while (steuerZeichen != Benutzerkommunikation.ENDE);
    Ausgabe.schreib("Das Programm wurde beendet.");
    }

  /**
   * Methode zum Anzeigen eines Startbildschirms.
   */
  private void zeigeSplashScreen()
    {
    Ausgabe.schreib("==============================");
    Ausgabe.neueZeile();
    Ausgabe.schreib(" Uebungsgruppenverwaltung 0.1");
    Ausgabe.neueZeile();
    Ausgabe.schreib("==============================");
    Ausgabe.neueZeile();
    }

  /**
   * Methode zum Einlesen der maximalen Anzahl an Teilnehmern pro Gruppe.
   * 
   * @return Anzahl der maximalen Teilnehmer pro Gruppe.
   */
  public int liesMaximaleAnzahlTeilnehmerProGruppe()
    {
    return this.liesPositivenInteger("Geben Sie die maximale Anzahl an Teilnehmern pro Gruppe an: ");
    }

  /**
   * Methode zum Einlesen der maximalen Anzahl an Gruppen.
   * 
   * @return Maximale Anzahl an Gruppen.
   */
  public int liesMaximaleAnzahlGruppen()
    {
    return this.liesPositivenInteger("Geben Sie die maximale Anzahl an Gruppen an: ");
    }

  /**
   * Methode zur Ausgabe des Benutzer-Auswahlmenus.
   */
  private void zeigeAuswahlMenuAn()
    {
    Ausgabe.neueZeile();
    Ausgabe.schreib("======================================================================================================================");
    Ausgabe.neueZeile();
    Ausgabe.schreib("Waehlen Sie eine Aufgabe (" + Benutzerkommunikation.TEILNEHMER_EINGEBEN + ": Teilnehmer eingeben, " + Benutzerkommunikation.GRUPPE_ANZEIGN + ": Uebungsgruppe anzeigen, " + Benutzerkommunikation.TEILNEHMER_ANZEIGEN + ": Alle Teilnehmer anzeigen, " + Benutzerkommunikation.ENDE + ": Ende): ");
    }

  /**
   * Methode zum Anzeigen einer Liste von Teilnehmern.
   * 
   * @param liste Liste der Teilnehmer, die angezeigt werden soll.
   */
  private void zeigeListeAn(TeilnehmendePerson[] liste)
    {
    Ausgabe.neueZeile();
    if (liste.length == 0)
      {
      Ausgabe.neueZeile();
      Ausgabe.schreib("  Keine Teilnehmer gefunden.");
      }
    else
      {
      Ausgabe.neueZeile();
      for (TeilnehmendePerson teilnehmendePerson : liste)
        {
        Ausgabe.schreib("  =====================================================");
        Ausgabe.neueZeile();
        Ausgabe.schreib("  " + teilnehmendePerson.getNachname() + ", ");
        Ausgabe.schreib(teilnehmendePerson.getVorname() + ", ");
        Ausgabe.neueZeile();
        Ausgabe.schreib("  Matrikelnummer: " + teilnehmendePerson.getMatrikelnummer() + ", ");
        Ausgabe.schreib("Semester: " + teilnehmendePerson.getSemester() + ", ");
        Ausgabe.schreib("Uebungsgruppe: " + teilnehmendePerson.getUebungsgruppe());
        Ausgabe.neueZeile();
        }
      Ausgabe.schreib("  =====================================================");
      }
    }

  /**
   * Methode zum Einlesen eines neuen Teilnehmers.
   */
  private void teilnehmerEingeben()
    {
    Ausgabe.schreib("  Nachname: ");
    String nachname = Eingabe.liesString();
    Ausgabe.schreib("  Vorname: ");
    String vorname = Eingabe.liesString();
    int matrikelnummer = this.liesPositivenInteger("  Matrikelnummer: ");
    int semester = this.liesPositivenInteger("  Semester: ");
    int uebungsgruppe = this.liesInteger("  Geben Sie die # der gewuenschten Uebungsgruppe ein: ", 1, this.uebungsgruppen.MAX_ANZAHL_GRUPPEN);

    if (this.uebungsgruppen.getTeilnehmerAnzahl() >= this.uebungsgruppen.MAX_ANZAHL_GRUPPEN * this.uebungsgruppen.MAX_ANZAHL_PRO_GRUPPE)
      {
      Ausgabe.neueZeile();
      Ausgabe.schreib("Die maximale Anzahl der Teilnehmer ist bereits erreicht.");
      } 
    else if (this.uebungsgruppen.getTeilnehmerAnzahlFuerGruppe(uebungsgruppe) >= this.uebungsgruppen.MAX_ANZAHL_PRO_GRUPPE)
      {
      Ausgabe.neueZeile();
      Ausgabe.schreib("Diese Uebungsgruppe ist bereits voll.");
      } 
    else
      {
      TeilnehmendePerson teilnehmendePerson = new TeilnehmendePerson(vorname, nachname, semester, matrikelnummer, uebungsgruppe);
      try
        {
        this.uebungsgruppen.teilnehmendePersonHinzufuegen(teilnehmendePerson);
        Ausgabe.neueZeile();
        Ausgabe.schreib("Teilnehmer aufgenommen.");
        } 
      catch (Exception e)
        {
        Ausgabe.neueZeile();
        Ausgabe.schreib("Unerwarteter Fehler: " + e.getMessage());
        Ausgabe.neueZeile();
        }
      }

    Ausgabe.neueZeile();
    }

  /**
   * Methode zum Einlesen eines Integers in einem vorgegegebenen Wertebereich. Der Benutzer wird so lange anufgefordert
   * einen Integer einzugeben, bis er im vorgegebenen Wertebereich liegt.
   * 
   * @param eingabeAufforderung Eingabeaufforderung zur Einagbe.
   * @param minimalerWert Untere Grenze des Wertebereichs.
   * @param maximalerWert Obere Grenze des Wertebereichs.
   * @return Der eingelesene Integer im vorgegegebenen Wertebereich.
   */
  private int liesInteger(String eingabeAufforderung, int minimalerWert, int maximalerWert)
    {
    int wert;
    Ausgabe.schreib(eingabeAufforderung);
    do
      {
      wert = Eingabe.liesInt();
      if (wert < minimalerWert || wert > maximalerWert)
        {
        Ausgabe.schreib("  Ungueltiger Wert, gueltig sind Werte von " + minimalerWert + "-" + maximalerWert + ", neuer Wert: ");
        }
      } while (wert < minimalerWert || wert > maximalerWert);
    return wert;
    }

  /**
   * Methode zum Einlesen eines positiven Integers. Der Benutzer wird so lange anufgefordert einen Integer einzugeben,
   * bis dieser positiv ist.
   * 
   * @param eingabeAufforderung Eingabeaufforderung zur Einagbe.
   * @return Der positiver eingelesene Integer.
   */
  private int liesPositivenInteger(String eingabeAufforderung)
    {
    int wert = 0;
    do
      {
      Ausgabe.schreib(eingabeAufforderung);
      wert = Eingabe.liesInt();
      if (wert <= 0)
        {
        Ausgabe.schreib("  Bitte geben Sie eine postivie Zahl ein: ");
        Ausgabe.neueZeile();
        }
      } while (wert <= 0);
    return wert;
    }
  }
